home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Programming / jikes-1.02 / src / long.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-08-26  |  16.3 KB  |  703 lines

  1. // $Id: long.cpp,v 1.7 1999/08/26 15:34:09 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <iostream.h>
  12. #include "long.h"
  13. #include "double.h"
  14. //
  15. // Note that the minimum long value, (0x80000000, 0x00000000), can be represented
  16. // exactly in a double field. However, the maximum long value, (0x7FFFFFFF, 0xFFFFFFFF)
  17. // cannot. To test if the double quantity "a" fits in a long range we will test whether
  18. // or not:
  19. //         (a >= min_long) && (-a > min_long)
  20. //
  21. BaseLong::operator LongInt()
  22. {
  23.     return LongInt(HighWord(), LowWord());
  24. }
  25.  
  26. BaseLong::operator ULongInt()
  27. {
  28.     return ULongInt(HighWord(), LowWord());
  29. }
  30.  
  31. bool BaseLong::operator== (BaseLong op)
  32. {
  33.     return ((HighWord() == op.HighWord()) && (LowWord() == op.LowWord()));
  34. }
  35.  
  36. bool BaseLong::operator!= (BaseLong op)
  37. {
  38.     return ((HighWord() != op.HighWord()) || (LowWord() != op.LowWord()));
  39. }
  40.  
  41. bool BaseLong::operator!()
  42. {
  43.     return (*this == 0);
  44. }
  45.  
  46. BaseLong BaseLong::operator~()
  47. {
  48.     return BaseLong(~HighWord(), ~LowWord());
  49. }
  50.  
  51. BaseLong BaseLong::operator^ (BaseLong op)
  52. {
  53.     return BaseLong(HighWord() ^ op.HighWord(), LowWord() ^ op.LowWord());
  54. }
  55.  
  56. BaseLong& BaseLong::operator^= (BaseLong op)
  57. {
  58.     *this = *this ^ op;
  59.     return *this;
  60. }
  61.  
  62. BaseLong BaseLong::operator| (BaseLong op)
  63. {
  64.     return BaseLong(HighWord() | op.HighWord(), LowWord() | op.LowWord());
  65. }
  66.  
  67. BaseLong& BaseLong::operator|= (BaseLong op)
  68. {
  69.     *this = *this | op;
  70.     return *this;
  71. }
  72.  
  73. BaseLong BaseLong::operator& (BaseLong op)
  74. {
  75.     return BaseLong(HighWord() & op.HighWord(), LowWord() & op.LowWord());
  76. }
  77.  
  78. BaseLong& BaseLong::operator&= (BaseLong op)
  79. {
  80.     *this = *this & op;
  81.     return *this;
  82. }
  83.  
  84. bool BaseLong::operator&& (BaseLong op)
  85. {
  86.     return (*this != 0) && (op != 0);
  87. }
  88.  
  89. bool BaseLong::operator|| (BaseLong op)
  90. {
  91.     return (*this != 0) || (op != 0);
  92. }
  93.  
  94. BaseLong BaseLong::operator<< (BaseLong op)
  95. {
  96.     u4 n = op.LowWord(); // Always treat this value as positive, since negative values are not allowed
  97.  
  98.     //
  99.     // Note that this function assumes that for two 32-bit integers
  100.     // x << y, where y = 0, is well-defined and that the result is
  101.     // the value x. This is true in Ansi-C and C++ but not true in
  102.     // old versions of C (See Kernighan and Ritchie).
  103.     // Note also that in shifting a 32-bit word, if y >= 32 then the
  104.     // result is unpredictable. On Aix, xlC will produce the result 0(good!)
  105.     // whereas on windows the Microsoft compiler produces the value of x(very bad !).
  106.     // That is the reason why we have the initial special check for (n == 0).
  107.     //
  108.     return (n == 0 ? *this
  109.                    : n < 32
  110.                        ? BaseLong((HighWord() << n) | (LowWord() >> (32 - n)), LowWord() << n)
  111.                        : BaseLong(LowWord() << (n - 32), 0));
  112. }
  113.  
  114. BaseLong& BaseLong::operator<<= (BaseLong op)
  115. {
  116.     *this = *this << op;
  117.     return *this;
  118. }
  119.  
  120. BaseLong BaseLong::operator+ (BaseLong op)
  121. {
  122.     u4 ushort1 = (LowWord() & 0xFFFF) + (op.LowWord() & 0xFFFF),
  123.        ushort2 = (ushort1 >> 16) + (LowWord() >> 16) + (op.LowWord() >> 16),
  124.        ushort3 = (ushort2 >> 16) + (HighWord() & 0xFFFF) + (op.HighWord() & 0xFFFF),
  125.        ushort4 = (ushort3 >> 16) + (HighWord() >> 16) + (op.HighWord() >> 16);
  126.  
  127.     return BaseLong((ushort3 & 0xFFFF) | (ushort4 << 16), (ushort1 & 0xFFFF) | (ushort2 << 16));
  128. }
  129.  
  130. BaseLong& BaseLong::operator+= (BaseLong op)
  131. {
  132.     *this = *this + op;
  133.     return *this;
  134. }
  135.  
  136. BaseLong BaseLong::operator++ (int dummy)
  137. {
  138.     BaseLong temp = *this;
  139.     *this += 1;
  140.     return temp;
  141. }
  142.  
  143. BaseLong BaseLong::operator++ ()
  144. {
  145.     *this += 1;
  146.     return *this;
  147. }
  148.  
  149. BaseLong BaseLong::operator- ()
  150. {
  151.     return ~(*this) + 1;
  152. }
  153.  
  154. BaseLong BaseLong::operator- (BaseLong op)
  155. {
  156.     return *this + (-op);
  157. }
  158.  
  159. BaseLong& BaseLong::operator-= (BaseLong op)
  160. {
  161.     *this = *this - op;
  162.     return *this;
  163. }
  164.  
  165. BaseLong BaseLong::operator-- (int dummy)
  166. {
  167.     BaseLong temp = *this;
  168.     *this -= 1;
  169.     return temp;
  170. }
  171.  
  172. BaseLong BaseLong::operator-- ()
  173. {
  174.     *this -= 1;
  175.     return *this;
  176. }
  177.  
  178. BaseLong BaseLong::operator* (BaseLong op)
  179. {
  180.     u4 x0 = this -> LowWord()   & 0xFFFF,
  181.        x1 = this -> LowWord()  >> 16,
  182.        x2 = this -> HighWord()  & 0xFFFF,
  183.        x3 = this -> HighWord() >> 16,
  184.  
  185.        y0 = op.LowWord()   & 0xFFFF,
  186.        y1 = op.LowWord()  >> 16,
  187.        y2 = op.HighWord()  & 0xFFFF,
  188.        y3 = op.HighWord() >> 16;
  189.  
  190.     BaseLong result = BaseLong(0, x0 * y0),
  191.              part1  = BaseLong(0, x0 * y1);
  192.     part1  <<= (1 << 4);
  193.     result += part1;
  194.     BaseLong part2  = BaseLong(0, x0 * y2);
  195.     part2  <<= (2 << 4);
  196.     result += part2;
  197.     BaseLong part3  = BaseLong(0, x0 * y3);
  198.     part3  <<= (3 << 4);
  199.     result += part3;
  200.  
  201.     BaseLong part4  = BaseLong(0, x1 * y0);
  202.     part4  <<= (1 << 4);
  203.     result += part4;
  204.     BaseLong part5  = BaseLong(0, x1 * y1);
  205.     part5  <<= (2 << 4);
  206.     result += part5;
  207.     BaseLong part6  = BaseLong(0, x1 * y2);
  208.     part6  <<= (3 << 4);
  209.     result += part6;
  210.     BaseLong part7  = BaseLong(0, x1 * y3);
  211.     part7  <<= (4 << 4);
  212.     result += part7;
  213.  
  214.     BaseLong part8  = BaseLong(0, x2 * y0);
  215.     part8  <<= (2 << 4);
  216.     result += part8;
  217.     BaseLong part9  = BaseLong(0, x2 * y1);
  218.     part9  <<= (3 << 4);
  219.     result += part9;
  220.     BaseLong part10 = BaseLong(0, x2 * y2);
  221.     part10 <<= (4 << 4);
  222.     result += part10;
  223.     BaseLong part11 = BaseLong(0, x2 * y3);
  224.     part11 <<= (5 << 4);
  225.     result += part11;
  226.  
  227.     BaseLong part12 = BaseLong(0, x3 * y0);
  228.     part12 <<= (3 << 4);
  229.     result += part12;
  230.     BaseLong part13 = BaseLong(0, x3 * y1);
  231.     part13 <<= (4 << 4);
  232.     result += part13;
  233.     BaseLong part14 = BaseLong(0, x3 * y2);
  234.     part14 <<= (5 << 4);
  235.     result += part14;
  236.     BaseLong part15 = BaseLong(0, x3 * y3);
  237.     part15 <<= (6 << 4);
  238.     result += part15;
  239.  
  240.     return result;
  241. }
  242.  
  243. BaseLong& BaseLong::operator*= (BaseLong op)
  244. {
  245.     *this = *this * op;
  246.     return *this;
  247. }
  248.  
  249.  
  250. BaseLong::BaseLong(u4 a, u4 b)
  251. {
  252.     HighWord() = a;
  253.     LowWord() = b;
  254. }
  255.  
  256. BaseLong::BaseLong(u4 a)
  257. {
  258.     HighWord() = 0;
  259.     LowWord() = a;
  260. }
  261.  
  262. BaseLong::BaseLong(i4 a)
  263. {
  264.     LowWord() = a;
  265.     //
  266.     // Since the carry is not guaranteed to ripple, we cannot use this code.
  267.     //
  268.     //        HighWord() = a >> 31;
  269.     //
  270.     HighWord() = (a < 0 ? 0xFFFFFFFF : 0x00000000);
  271. }
  272.  
  273.  
  274. void BaseLong::Divide(BaseLong dividend, BaseLong divisor, BaseLong "ient, BaseLong &remainder)
  275. {
  276.     u4 high = dividend.HighWord(),
  277.        low  = dividend.LowWord(),
  278.        remainder_high = 0;
  279.  
  280.     for (int i = 0; i < 32; i++)
  281.     {
  282.         remainder_high = (remainder_high << 1) | (high >> 31);
  283.         high <<= 1;
  284.         if ((ULongInt) divisor <= remainder_high)
  285.         {
  286.             high++;
  287.             remainder_high -= divisor.LowWord();
  288.         }
  289.     }
  290.  
  291.     remainder = BaseLong(0, remainder_high);
  292.  
  293.     for (int j = 0; j < 32; j++)
  294.     {
  295.         remainder <<= 1;
  296.         remainder.LowWord() |= (low >> 31);
  297.         low <<= 1;
  298.         if ((ULongInt) divisor <= remainder)
  299.         {
  300.             low++;
  301.             remainder -= divisor;
  302.         }
  303.     }
  304.  
  305.     quotient = BaseLong(high, low);
  306.  
  307.     return;
  308. }
  309.  
  310.  
  311. void ULongInt::OctString(char *result, bool show_base)
  312. {
  313.     ULongInt val = *this;
  314.     char *ptr = result;
  315.  
  316.     do
  317.     {
  318.         *ptr++ = '0' + (val % 8).LowWord();
  319.         val /= 8;
  320.     } while (val != 0);
  321.  
  322.     if (show_base)
  323.         *ptr++ = '0';
  324.  
  325.     *ptr = U_NULL;
  326.  
  327.     for (char *tail = ptr - 1; tail > result; tail--, result++)
  328.     {
  329.         char c = *tail;
  330.         *tail = *result;
  331.         *result = c;
  332.     }
  333.  
  334.     return;
  335. }
  336.  
  337.  
  338. void ULongInt::DecString(char *result)
  339. {
  340.     ULongInt val = *this;
  341.     char *ptr = result;
  342.  
  343.     do
  344.     {
  345.         *ptr++ = '0' + (val % 10).LowWord();
  346.         val /= 10;
  347.     } while (val != 0);
  348.  
  349.     *ptr = U_NULL;
  350.  
  351.     for (char *tail = ptr - 1; tail > result; tail--, result++)
  352.     {
  353.         char c = *tail;
  354.         *tail = *result;
  355.         *result = c;
  356.     }
  357.  
  358.     return;
  359. }
  360.  
  361.  
  362. void ULongInt::HexString(char *result, bool show_base)
  363. {
  364.     ULongInt val = *this;
  365.     char *ptr = result;
  366.  
  367.     do
  368.     {
  369.         *ptr++ = '0' + (val % 16).LowWord();
  370.         val /= 16;
  371.     } while (val != 0);
  372.  
  373.     if (show_base)
  374.     {
  375.         *ptr++ = 'x';
  376.         *ptr++ = '0';
  377.     }
  378.  
  379.     *ptr = U_NULL;
  380.  
  381.     for (char *tail = ptr - 1; tail > result; tail--, result++)
  382.     {
  383.         char c = *tail;
  384.         *tail = *result;
  385.         *result = c;
  386.     }
  387.  
  388.     return;
  389. }
  390.  
  391.  
  392. void LongInt::OctString(char *result, bool show_base)
  393. {
  394.     ULongInt val;
  395.  
  396.     if (HighWord() & 0x80000000)
  397.     {
  398.         *result++ = '-';
  399.         val = -(*this);
  400.     }
  401.     else val = *this;
  402.  
  403.     val.OctString(result, show_base);
  404.  
  405.     return;
  406. }
  407.  
  408. void LongInt::DecString(char *result)
  409. {
  410.     ULongInt val;
  411.  
  412.     if (HighWord() & 0x80000000)
  413.     {
  414.         *result++ = '-';
  415.         val = -(*this);
  416.     }
  417.     else val = *this;
  418.  
  419.     val.DecString(result);
  420.  
  421.     return;
  422. }
  423.  
  424. void LongInt::HexString(char *result, bool show_base)
  425. {
  426.     ULongInt val;
  427.  
  428.     if (HighWord() & 0x80000000)
  429.     {
  430.         *result++ = '-';
  431.         val = -(*this);
  432.     }
  433.     else val = *this;
  434.  
  435.     val.HexString(result, show_base);
  436.  
  437.     return;
  438. }
  439.  
  440. ULongInt& ULongInt::operator/= (ULongInt op)
  441. {
  442.     *this = *this / op;
  443.     return *this;
  444. }
  445.  
  446.  
  447. ULongInt ULongInt::operator/ (ULongInt op)
  448. {
  449.     BaseLong quotient,
  450.              remainder;
  451.  
  452.     Divide(*this, op, quotient, remainder);
  453.  
  454.     return quotient;
  455. }
  456.  
  457. ULongInt ULongInt::operator% (ULongInt op)
  458. {
  459.     BaseLong quotient,
  460.              remainder;
  461.  
  462.     Divide(*this, op, quotient, remainder);
  463.  
  464.     return remainder;
  465. }
  466.  
  467. ULongInt& ULongInt::operator%= (ULongInt op)
  468. {
  469.     *this = *this % op;
  470.     return *this;
  471. }
  472.  
  473.  
  474. ULongInt ULongInt::operator>> (ULongInt op)
  475. {
  476.     u4 n = op.LowWord(); // Always treat this value as positive, since negative values are not allowed
  477.  
  478.     //
  479.     // Note that this function assumes that for two 32-bit integers
  480.     // x >> y, where y = 0, is well-defined and that the result is
  481.     // the value x. This is true in Ansi-C and C++ but not true in
  482.     // old versions of C (See Kernighan and Ritchie).
  483.     // Note also that in shifting a 32-bit word, if y >= 32 then the
  484.     // result is unpredictable. On Aix, xlC will produce the result 0(good!)
  485.     // whereas on windows the Microsoft compiler produces the value of x(very bad !).
  486.     // That is the reason why we have the initial special check for (n == 0).
  487.     //
  488.     return (n == 0 ? *this
  489.                    : n < 32
  490.                        ? ULongInt(HighWord() >> n, (HighWord() << (32 - n)) | (LowWord() >> n))
  491.                        : ULongInt(0, HighWord() >> (n - 32)));
  492. }
  493.  
  494. ULongInt& ULongInt::operator>>= (ULongInt op)
  495. {
  496.     *this = *this >> op;
  497.     return *this;
  498. }
  499.  
  500. bool ULongInt::operator< (ULongInt op)
  501. {
  502.     return (HighWord() == op.HighWord() ? LowWord() < op.LowWord() : HighWord() < op.HighWord());
  503. }
  504.  
  505. bool ULongInt::operator<= (ULongInt op)
  506. {
  507.     return (HighWord() == op.HighWord() ? LowWord() <= op.LowWord() : HighWord() <= op.HighWord());
  508. }
  509.  
  510. bool ULongInt::operator> (ULongInt op)
  511. {
  512.     return (HighWord() == op.HighWord() ? LowWord() > op.LowWord() : HighWord() > op.HighWord());
  513. }
  514.  
  515. bool ULongInt::operator>= (ULongInt op)
  516. {
  517.     return (HighWord() == op.HighWord() ? LowWord() >= op.LowWord() : HighWord() >= op.HighWord());
  518. }
  519.  
  520. // This conversion from double to LongInt is performed according to the rules
  521. // specified in the Java Language Specification.
  522. //
  523. LongInt::LongInt(IEEEfloat a) : BaseLong(0,0)
  524. {
  525.     IEEEdouble value = IEEEdouble(a);
  526.     LongInt lvalue = LongInt(value);
  527.     HighWord() = lvalue.HighWord();
  528.     LowWord() = lvalue.LowWord();
  529.     return;
  530. }
  531.  
  532. LongInt::LongInt(IEEEdouble a) : BaseLong (0,0)
  533. {
  534.     if (a.HighWord() == 0x7fffffff && a.LowWord() == 0xffffffff) // if NaN
  535.         ; // *this is already initialized to 0
  536.     else if (a.HighWord() == 0xfff00000 && a.LowWord() == 0x00000000) // if NEGATIVE_INFINITY())
  537.         HighWord() = 0x80000000;
  538.     else if (a.HighWord() == 0x7ff00000 && a.LowWord() == 0x00000000) // if POSITIVE_INFINITY())
  539.     {
  540.         HighWord() = 0x7FFFFFFF;
  541.         LowWord()  = 0xFFFFFFFF;
  542.     }
  543.     else
  544.     {
  545.         double b = floor(a.DoubleValue() < 0.0 ? -a.DoubleValue() : a.DoubleValue()); // DSDouble
  546.  
  547.         if (b < IEEEdouble::min_long.DoubleValue())
  548.             HighWord() = 0x80000000;
  549.         else if (-b <= IEEEdouble::min_long.DoubleValue())
  550.         {
  551.             HighWord() = 0x7FFFFFFF;
  552.             LowWord()  = 0xFFFFFFFF;
  553.         }
  554.         else
  555.         {
  556.             LongInt multiplier = 1;
  557.  
  558.             while (b > 0.0)
  559.             {
  560.                 *this += (multiplier * (int) fmod(b, 10));
  561.                 b /=  10.0;
  562.                 multiplier *= 10;
  563.             }
  564.  
  565.             if (a < 0.0)
  566.                 *this = -(*this);
  567.         }
  568.     }
  569.  
  570.     return;
  571. }
  572.  
  573. LongInt LongInt::operator/ (LongInt op)
  574. {
  575.     bool negative_dividend = ((HighWord() & 0x80000000) != 0),
  576.          negative_divisor  = ((op.HighWord() & 0x80000000) != 0);
  577.  
  578.     BaseLong a = (negative_dividend ? -(*this) : (BaseLong) *this),
  579.              b = (negative_divisor  ? -(op)    : (BaseLong) op),
  580.              quotient,
  581.              remainder;
  582.  
  583.     Divide(a, b, quotient, remainder);
  584.  
  585.     return (negative_dividend ^ negative_divisor ? -quotient : quotient);
  586. }
  587.  
  588. LongInt& LongInt::operator/= (LongInt op)
  589. {
  590.     *this = *this / op;
  591.     return *this;
  592. }
  593.  
  594. LongInt LongInt::operator% (LongInt op)
  595. {
  596.     bool negative_dividend = ((HighWord() & 0x80000000) != 0),
  597.     negative_divisor  = ((op.HighWord() & 0x80000000) != 0);
  598.  
  599.     BaseLong a = (negative_dividend ? -(*this) : (BaseLong) *this),
  600.              b = (negative_divisor  ? -(op)    : (BaseLong) op),
  601.              quotient,
  602.              remainder;
  603.  
  604.     Divide(a, b, quotient, remainder);
  605.  
  606.     return (negative_dividend ? -remainder : remainder);
  607. }
  608.  
  609. LongInt& LongInt::operator%= (LongInt op)
  610. {
  611.     *this = *this % op;
  612.     return *this;
  613. }
  614.  
  615. LongInt LongInt::operator>> (LongInt op)
  616. {
  617.     u4 n = op.LowWord(); // Always treat this value as positive, since negative values are not allowed
  618.  
  619.     //
  620.     // Note that this function assumes that for two 32-bit integers
  621.     // x >> y, where y = 0, is well-defined and that the result is
  622.     // the value x. This is true in Ansi-C and C++ but not true in
  623.     // old versions of C (See Kernighan and Ritchie).
  624.     //
  625.     // Note also that in shifting a 32-bit word, if y >= 32 then the
  626.     // result is unpredictable. On Aix, xlC will produce the result 0(good!)
  627.     // whereas on windows the Microsoft compiler produces the value of x(very bad !).
  628.     // That is the reason why we have the initial special check for (n == 0).
  629.     //
  630.     // Finally, note that the right-shitfting of the HighWord is not guaranteed
  631.     // to ripple the carry bit. Whether or not the carry-bit is rippled is
  632.     // implementation-dependent. Therefore, this implementation is designed to
  633.     // shift the "long" quantity in a similar manner as the system (compiler + environement)
  634.     // used to compile it would shift a 32-bit signed integer.
  635.     //
  636.     return (n == 0 ? *this
  637.                    : n < 32
  638.                        ? LongInt(((i4) HighWord()) >> n, (HighWord() << (32 - n)) | (LowWord() >> n))
  639.                        : LongInt(((i4) HighWord()) >> 31, ((i4) HighWord()) >> (n - 32)));
  640. }
  641.  
  642. LongInt& LongInt::operator>>= (LongInt op)
  643. {
  644.     *this = *this >> op;
  645.     return *this;
  646. }
  647.  
  648. bool LongInt::operator< (LongInt op)
  649. {
  650.     return (HighWord() == op.HighWord() ? LowWord() < op.LowWord() : (i4) HighWord() < (i4) op.HighWord());
  651. }
  652.  
  653. bool LongInt::operator<= (LongInt op)
  654. {
  655.     return (HighWord() == op.HighWord() ? LowWord() <= op.LowWord() : (i4) HighWord() <= (i4) op.HighWord());
  656. }
  657.  
  658. bool LongInt::operator> (LongInt op)
  659. {
  660.     return (HighWord() == op.HighWord() ? LowWord() > op.LowWord() : (i4) HighWord() > (i4) op.HighWord());
  661. }
  662.  
  663. bool LongInt::operator>= (LongInt op)
  664. {
  665.     return (HighWord() == op.HighWord() ? LowWord() >= op.LowWord() : (i4) HighWord() >= (i4) op.HighWord());
  666. }
  667.  
  668. double ULongInt::Double()
  669. {
  670.     double val = 0.0,
  671.            multiplier = 1.0;
  672.     ULongInt num = *this;
  673.  
  674.     while (num > 0)
  675.     {
  676.         val += (multiplier * (num % 10).LowWord());
  677.         num /= 10;
  678.         multiplier *= 10.0;
  679.     }
  680.  
  681.     return val;
  682. }
  683.  
  684. double LongInt::Double()
  685. {
  686.     double val;
  687.     ULongInt num;
  688.  
  689.     if (*this < 0)
  690.     {
  691.         num = -(*this);
  692.         val = -num.Double();
  693.     }
  694.     else
  695.     {
  696.         num = *this;
  697.         val = num.Double();
  698.     }
  699.  
  700.     return val;
  701. }
  702.  
  703.